﻿using Newtonsoft.Json;
using Newtonsoft.Json.UnityConverters.Math;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public static class JsonUtil
{
    private static JsonSerializerSettings _jsonSerializerSettings;

    public static void SerializeToFile(object obj, string path)
    {
        //这一串都是为了格式化输出json
        StringWriter textWriter = new StringWriter();
        JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
        {
            Formatting = Formatting.Indented,
            Indentation = 4,
            IndentChar = ' ',
        };

        JsonSerializer serializer = JsonSerializer.Create(GetJsonSerializerSettings());

        //排序

        serializer.Serialize(jsonWriter, obj);
        var file = new FileInfo(path);

        System.IO.File.WriteAllText(file.FullName, textWriter.ToString());
        jsonWriter.Close();
        textWriter.Close();

        return;
    }

    public static string Serialize(object obj, bool format = true)
    {
        //这一串都是为了格式化输出json
        StringWriter textWriter = new StringWriter();

        JsonTextWriter jsonWriter = null;
        if (format) jsonWriter = new JsonTextWriter(textWriter)
        {
            Formatting = Formatting.Indented,
            Indentation = 4,
            IndentChar = ' ',
        };
        else
        {
            jsonWriter = new JsonTextWriter(textWriter);
        }
        JsonSerializer serializer = JsonSerializer.Create(GetJsonSerializerSettings());

        //排序

        serializer.Serialize(jsonWriter, obj);

        return textWriter.ToString();
    }

    public static T Deserialize<T>(string json)
    {
        return JsonConvert.DeserializeObject<T>(json, GetJsonSerializerSettings());
    }
    public static object Deserialize(string json, Type type)
    {
        return JsonConvert.DeserializeObject(json, type, GetJsonSerializerSettings());
    }
    public static JsonSerializerSettings GetJsonSerializerSettings()
    {
        if (_jsonSerializerSettings != null)
        {
            return _jsonSerializerSettings;
        }

        //自动带入类型
        var setting = new JsonSerializerSettings()
        {
            Converters = new List<JsonConverter> {
                new Vector2Converter(),
                new Vector3Converter(),
                new Vector2IntConverter(),
                new Vector3IntConverter(),
            },
            TypeNameHandling = TypeNameHandling.Auto,
            NullValueHandling = NullValueHandling.Ignore,
        };

        _jsonSerializerSettings = setting;
        return setting;
    }
}


/// <summary>
/// 字典类型转换器
/// </summary>
/// <typeparam name="Key"></typeparam>
/// <typeparam name="Value"></typeparam>
public class DictionaryJsonConverter<Key, Value> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(IDictionary<Key, Value>).IsAssignableFrom(objectType);
    }


    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var dictionary = new Dictionary<Key, Value>();

        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.EndObject)
            {
                return dictionary;
            }

            if (reader.TokenType != JsonToken.PropertyName)
            {
                throw new JsonException();
            }

            //序列化Key
            string propertyName = reader.Value.ToString();
            var key = JsonUtil.Deserialize<Key>(propertyName);

            //序列化Value
            reader.Read();
            var value = serializer.Deserialize<Value>(reader);

            dictionary.Add(key, value);
        }
        throw new NotImplementedException();
    }



    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        if (value is IDictionary<Key, Value> v)
            foreach (var item in v)
            {
                var propertyName = JsonUtil.Serialize(item.Key, false);
                writer.WritePropertyName(propertyName);
                serializer.Serialize(writer, item.Value);
            }
        else throw new NotImplementedException();
        writer.WriteEndObject();
    }

}
